#include <iostream>
#include <stdio.h>
#include "Person.h"
#include "Dog.h"
//标准命名空间，cout cin都是在该命名空间中命名的
using namespace std;
//自定义命名空间
namespace denglb
{
	void my_fun(int i)
	{
		cout << "denglb:" << i << endl;
	}
}
namespace denglb2
{
	void my_fun(int i)
	{
		cout << "denglb2:" << i << endl;
	}
}
//无名称的命名空间,空间中的内容外部不能使用,只能内部使用,很少使用
namespace
{

}
//类
class Demo
{
private:
	int a = 10;
public:
	Demo()
	{
		std::cout << "构造函数" << endl;
	}
	Demo(int i)
	{
		std::cout << "有参构造函数" << endl;
	}
	Demo(const Demo &demo)
	{
		this->a = demo.a;
		std::cout << "拷贝构造函数" << endl;
	}
	~Demo()
	{
		std::cout << "析构函数" << endl;
	}
};

void my_demo()
{
	Demo demos[3] = { Demo(),Demo(),Demo(2) };
}

//单利模式测试
void my_person()
{
	Person * p = Person::get_Instance();
	//调用内联函数,不是真正的函数调用(压栈出栈),而是代码替换
	p->print();
	p->set_age(23);
	p->set_name("张三");
	cout << p->get_age() << endl;
	cout << p->get_name() << endl;
	cout << p->get_gender() << endl;
	system("pause");
	Person::release();
}
//new操作符分配内存
//delete释放内存
void my_new()
{
	//数组
	int * arr = new int[10];
	for (int i = 0; i < 10; i++)
	{
		arr[i] = i;
	}
	for (int i = 0; i < 10; i++)
	{
		cout << i << endl;
	}
	//释放数组所占的内存
	delete []arr;
}

//通过引用修改变量的值（通过引用直接修改变量的值,不会分配内存来接收参数,没有压栈和出栈操作,效率高)
void chanage_i(int &i)
{
	i = 40;
}
//常量引用,防止修改
void const_reference(const int &i)
{

}
//引用(就是这个变量的一个别名,与地址无关,必须要先有变量,然后才有这个变量的引用)
void my_refrence()
{
	int i = 10;
	int & b = i;
	//是同一个地址
	cout << &i <<"--"<< &b << endl;

	//这里传的i的引用
	chanage_i(i);
	cout << i << endl; //40
}

//缺省参数,只能放在最后
void my_default_arg(int i,int a = 10)
{
	cout << i << "---" << a << endl;
}

//调用有缺省参数的函数,缺省参数可以不传
void test_default_arg()
{
	//缺省参数可传可不传
	my_default_arg(12);
	my_default_arg(12, 34);
}

//函数重载：函数名相同,参数不同（注意缺省参数）,不能通过返回值得类型来实现重载
void func(int a, int b)
{
	cout << a << "--" << b << endl;
}
void func(int a, int b, int c)
{
	cout << a << "--" << b << "--" << c <<endl;
}
//模板函数(内部会根据具体类型生成该类型的函数)
template <class T>
T add(T t1, T t2)
{
	return t1 + t2;
}
//调用模板函数
void test_template()
{
	double a = 1.4;
	double b = 2.5;
	cout << add<double>(a, b) << endl;

	int c = 1;
	int d = 2;
	cout << add<int>(c, d) << endl;

	char ch1 = '1';
	char ch2 = '2';
	cout << add<char>(ch1, ch2) << endl;
}
//调用命名空间中的函数
void namespace_fun()
{
	denglb::my_fun(2);
	denglb2::my_fun(3);
}

//拷贝构造
void copy_construct()
{

/*
//栈中创建对象
	Dog dog1 = Dog("小花");
	cout << dog1.get_name() << endl;
	Dog dog2 = dog1;
	cout << dog2.get_name() << endl;
*/
//堆中创建对象
	Dog *dog1 = new Dog("小花");
	cout << dog1->get_name() << endl;
	//拷贝(拷贝的对象在栈中,函数执行完,就销毁)
	Dog dog2 = *dog1;
	cout << dog2.get_name() << endl;
	delete(dog1);
}
//对象的引用作为函数参数(防止函数内存修改对象的属性,加const),如果是对象作为函数参数,那么传入的是对象的一份拷贝(会执行一次拷贝构造函数)
void object_arg(const Dog& dog)
{
	cout << dog.get_name() << endl;
}

void test_object_arg()
{
	Dog dog =  Dog("小花");

	//Dog dog2 = "旺财"; //如果构造函数加了explicit关键字,就不能这么写,不加的话默认是implicit,可以这么写
	object_arg(dog);
	cout << dog.get_name() << endl;

}

void _1main()
{
	//my_person();
	//my_new();
	//my_refrence();
	//test_default_arg();
	//test_template();
	//copy_construct();
	//test_object_arg();
}